package org.whh.automatic.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.whh.automatic.model.AutoTask;
import org.whh.automatic.service.AutoTaskService;
import org.whh.automatic.service.TaskExecutorService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 自动任务控制器
 * <p>
 * 提供自动化任务的RESTful API接口，主要功能包括：
 * 1. 获取任务列表和任务详情
 * 2. 获取任务所需的动态值信息
 * 3. 执行任务（支持动态值注入）
 * <p>
 * 所有接口都以/api/tasks为基础路径
 */
@RestController
@RequestMapping("/api/tasks")
public class AutoTaskController {

    /**
     * 日志记录器
     */
    private static final Logger logger = LoggerFactory.getLogger(AutoTaskController.class);

    /**
     * 任务管理服务
     */
    @Autowired
    private AutoTaskService taskService;

    /**
     * 任务执行服务
     */
    @Autowired
    private TaskExecutorService executorService;

    /**
     * 获取所有任务
     * <p>
     * GET /api/tasks
     * 返回系统中所有已保存的任务名称列表
     *
     * @return 包含所有任务名称的列表
     */
    @GetMapping
    public ResponseEntity<List<String>> getAllTasks() {
        List<String> taskNames = taskService.getAllTaskNames();
        return ResponseEntity.ok(taskNames);
    }

    /**
     * 获取任务信息
     * <p>
     * GET /api/tasks/taskInfo?taskName={taskName}
     * 返回指定任务的详细配置信息
     *
     * @param taskName 要查询的任务名称
     * @return 如果任务存在，返回任务配置信息；否则返回404
     */
    @GetMapping("/taskInfo")
    public ResponseEntity<?> getTask(@RequestParam(name = "taskName") String taskName) {
        AutoTask task = taskService.loadTask(taskName);
        if (task == null) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(task);
    }

    /**
     * 获取任务所需的动态值
     * <p>
     * GET /api/tasks/dynamic-values?taskName={taskName}
     * 返回指定任务所需的所有动态值名称及其默认值（空字符串）
     *
     * @param taskName 要查询的任务名称
     * @return 如果任务存在，返回动态值映射表；否则返回404
     */
    @GetMapping("/dynamic-values")
    public ResponseEntity<?> getRequiredDynamicValues(@RequestParam(name = "taskName") String taskName) {
        AutoTask task = taskService.loadTask(taskName);
        if (task == null) {
            return ResponseEntity.notFound().build();
        }
        Set<String> dynamicValueNames = task.getRequiredDynamicValueNames();
        Map<String, String> result = new HashMap<>();
        for (String name : dynamicValueNames) {
            result.put(name, "");
        }

        return ResponseEntity.ok(result);
    }


    /**
     * 执行任务
     * <p>
     * POST /api/tasks/execute?taskName={taskName}
     * 异步执行指定的任务，支持通过请求体传入动态值
     * <p>
     * 请求体格式示例：
     * {
     * "dynamicValues": {
     * "value1": "text1",
     * "value2": "text2"
     * }
     * }
     * <p>
     * 执行流程：
     * 1. 加载指定任务
     * 2. 设置动态值（如果有）
     * 3. 验证所有必需的动态值是否都已设置
     * 4. 在新线程中异步执行任务
     *
     * @param taskName 要执行的任务名称
     * @param request  包含动态值的请求对象（可选）
     * @return - 如果任务不存在，返回404
     * - 如果缺少必需的动态值，返回400和缺少的值列表
     * - 如果任务开始执行，返回成功状态
     */
    @PostMapping("/execute")
    public ResponseEntity<?> executeTask(@RequestParam(name = "taskName") String taskName, @RequestBody(required = false) ExecuteTaskRequest request) {

        logger.info("收到执行任务请求: {}", taskName);

        // 加载任务配置
        AutoTask task = taskService.loadTask(taskName);
        if (task == null) {
            return ResponseEntity.notFound().build();
        }

        // 设置动态值（如果请求中包含）
        if (request != null && request.getDynamicValues() != null) {
            for (Map.Entry<String, String> entry : request.getDynamicValues().entrySet()) {
                task.setDynamicValue(entry.getKey(), entry.getValue());
            }
        }

        // 验证是否所有必需的动态值都已设置
        Set<String> requiredNames = task.getRequiredDynamicValueNames();
        if (!requiredNames.isEmpty()) {
            if (!task.areAllDynamicValuesSet()) {
                Map<String, Object> error = new HashMap<>();
                error.put("error", "缺少必要的动态值");
                error.put("requiredValues", requiredNames);
                return ResponseEntity.badRequest().body(error);
            }
        }

        // 在新线程中异步执行任务
        new Thread(() -> {
            try {
                executorService.executeTask(task);
            } catch (Exception e) {
                logger.error("执行任务失败: " + taskName, e);
            }
        }).start();

        // 返回成功响应
        Map<String, String> result = new HashMap<>();
        result.put("status", "任务开始执行");
        return ResponseEntity.ok(result);
    }

    /**
     * 执行任务请求对象
     * <p>
     * 用于封装执行任务API的请求体数据
     */
    public static class ExecuteTaskRequest {
        /**
         * 动态值映射表
         */
        private Map<String, String> dynamicValues;

        public Map<String, String> getDynamicValues() {
            return dynamicValues;
        }
    }
}
